<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function t1(a, b) {
        console.log("这是t1()函数");
        // console.log(a, b);
        // //每个函数对象都有一个arguments
        // console.log(arguments);
        // //函数的本身，但是在严格，无效
        // console.log(arguments.callee);
        // console.log(arguments.callee === t1);
        //
        // console.log(t1.caller);
        console.log(this);//函数的调用者所在的执行环境
    }

    t1(1, 2, 3);//调用函数
    console.log(t1.length);//打印函数的属性，函数本身不会被调用

    function t2() {
        console.log("t2调用了t1")
        t1();
        console.log(this);
    }

    t2();

    function Person() {
        if (!new.target) {
            throw new Error("Person是一个构造函数，必须通过new来调用");
        }
        this.name = "张三";
        this.age = 18;
        console.log(new.target);
        console.log(this);//构造函数中的this，指向的是创建的对象
    }

    //最终有一个return，返回创建的对象
    let p = new Person();
    console.log(p);
    let p1 = new Person();
    console.log(p1);
    // let p1 = Person();
    // console.log(p1);
    //
    // let set = Set();

    console.log(t1.prototype);
    console.log(t2.prototype);

    function t3(a, b) {
        console.log(this);//默认指定window
        console.log(a, b);
    }

    t3();//调用t3，this指定默认的执行环境
    //apply，参数必须放在数组中
    t3.apply(p, [1, 2, 3]);//调用了t3，this指向p对象
    //支持...扩展运算符
    t3.call(p, 1, 2, 3);
    t3.call(p, ...[1, 2, 3]);

    // t3.bind(p, 4, 5, 6)();
    let t4 = t3.bind(p, 4, 5, 6);
    t4();
</script>
</body>
</html>